<!-- 代码已包含 CSS：使用 TailwindCSS , 安装 TailwindCSS 后方可看到布局样式效果 -->
<template>
	<div class="min-h-screen bg-gray-50">
		<div v-show="showLoading"
			class="fixed inset-0 bg-gray-900/50 backdrop-blur-sm flex items-center justify-center z-50">
			<div class="bg-white rounded-lg p-8 flex flex-col items-center">
				<div class="w-16 h-16 border-4 border-blue-600 border-t-transparent rounded-full animate-spin mb-4">
				</div>
				<p class="text-lg font-medium text-gray-800">AI 智能分析中...</p>
				<p class="text-sm text-gray-500 mt-2">正在为您分配部门</p>
			</div>
		</div>
		<nav class="bg-white shadow-sm h-16 flex items-center px-6 fixed w-full z-10">
			<h1 class="text-xl font-bold text-gray-800">JBolt AI客户投诉智能分类推送</h1>
			<div class="ml-auto flex items-center gap-4">
				<div class="relative">
					<input type="text" placeholder="搜索投诉" v-model="keywords"
						class="pl-10 pr-4 py-2 rounded-lg border-gray-200 border focus:outline-none focus:border-blue-500 text-sm w-64">
					<i class="fas fa-search absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 text-sm"></i>
				</div>
				<button @click="showAddComplaint = true"
					class="!rounded-button flex items-center gap-2 bg-blue-500 text-white px-4 py-2 text-sm hover:bg-blue-600 transition-colors whitespace-nowrap">
					<i class="fas fa-plus"></i>
					新建投诉
				</button>
			</div>
		</nav>
		<div class="flex h-screen pt-16">
			<!-- 左侧菜单 -->
			<div class="w-64 bg-white border-r border-gray-200 flex flex-col">
				<div class="p-4">
					<div class="text-sm font-medium text-gray-500 mb-2">功能分类</div>
					<div class="space-y-1">
						<button @click="activeMenu = null" :class="{'bg-blue-50 text-blue-600': activeMenu === null}"
							class="!rounded-button flex items-center gap-3 w-full px-3 py-2 text-left text-sm hover:bg-gray-50 whitespace-nowrap">
							<i class="fas fa-list-ul w-5"></i>
							投诉列表
							<span
								class="ml-auto bg-gray-100 text-gray-600 px-2 py-0.5 text-xs rounded-full">{{ totalComplaints }}</span>
						</button>
						<button @click="activeMenu = 1" :class="{'bg-blue-50 text-blue-600': activeMenu === 1}"
							class="!rounded-button flex items-center gap-3 w-full px-3 py-2 text-left text-sm hover:bg-gray-50 whitespace-nowrap">
							<i class="fas fa-laptop-code w-5"></i>
							技术部处理
							<span
								class="ml-auto bg-gray-100 text-gray-600 px-2 py-0.5 text-xs rounded-full">{{ techComplaints }}</span>
						</button>
						<button @click="activeMenu = 2" :class="{'bg-blue-50 text-blue-600': activeMenu === 2}"
							class="!rounded-button flex items-center gap-3 w-full px-3 py-2 text-left text-sm hover:bg-gray-50 whitespace-nowrap">
							<i class="fas fa-chart-line w-5"></i>
							市场部处理
							<span
								class="ml-auto bg-gray-100 text-gray-600 px-2 py-0.5 text-xs rounded-full">{{ marketComplaints }}</span>
						</button>
						<button @click="activeMenu = 3" :class="{'bg-blue-50 text-blue-600': activeMenu === 3}"
							class="!rounded-button flex items-center gap-3 w-full px-3 py-2 text-left text-sm hover:bg-gray-50 whitespace-nowrap">
							<i class="fas fa-headset w-5"></i>
							客服部处理
							<span
								class="ml-auto bg-gray-100 text-gray-600 px-2 py-0.5 text-xs rounded-full">{{ serviceComplaints }}</span>
						</button>
					</div>
				</div>
				<div class="flex-1 p-4">
					<div class="text-sm font-medium text-gray-500 mb-2">部门投诉比例</div>
					<div ref="chartContainer" class="w-full h-64"></div>
				</div>
			</div>
			<!-- 右侧内容 -->
			<div class="flex-1 p-6 overflow-auto" @scroll="handleScroll">
				<div class="grid grid-cols-1 gap-4" v-if="show">
					<div v-for="complaint in complaints" :key="complaint.id"
						class="bg-white p-6 rounded-lg shadow-sm border border-gray-200">
						<div class="flex items-start justify-between mb-4">
							<div>
								<h3 class="text-lg font-medium text-gray-900">{{ complaint.title }}</h3>
								<p class="text-sm text-gray-500 mt-1">投诉编号：{{ complaint.id }} |
									提交时间：{{ complaint.createTime }}</p>
							</div>
							<div class="flex items-center gap-2">
								<span class="px-3 py-1 rounded-full text-sm font-medium bg-gray-50 text-gray-600">
									<i class="fas"
										:class="{'fa-laptop-code': complaint.deptId === '1','fa-chart-line': complaint.deptId === '2','fa-headset': complaint.deptId === '3'}"></i>
									{{ complaint.deptId === '1' ? '智能分配到技术部' :complaint.deptId === '2' ? '智能分配到市场部' :complaint.deptId === '3' ? '智能分配到客服部' : '待分配' }}
								</span>
								<span :class="statusClasses[complaint.status]"
									class="px-3 py-1 rounded-full text-sm font-medium">
									{{ complaint.status }}
								</span>
							</div>
						</div>
						<p class="text-gray-700 mb-4">{{ complaint.content }}</p>
						<div class="flex items-center justify-between">
							<div class="flex items-center gap-3">
								<img src="https://assets.d2danao.com/ai/2025-01-14/MAu3ly默认头像.png" alt="用户头像"
									class="w-8 h-8 rounded-full">
								<div>
									<div class="text-sm font-medium text-gray-900">{{ complaint.userName }}</div>
									<div class="text-sm text-gray-500">手机：{{ complaint.userPhone }}</div>
								</div>
							</div>
							<div class="flex items-center gap-2">
								<button @click="showToast('可自行完成相应功能开发')"
									class="!rounded-button bg-blue-50 text-blue-600 px-3 py-1.5 text-sm hover:bg-blue-100 transition-colors whitespace-nowrap">
									<i class="fas fa-reply mr-1"></i>
									回复
								</button>
								<button @click="showToast('可自行完成相应功能开发')"
									class="!rounded-button bg-green-50 text-green-600 px-3 py-1.5 text-sm hover:bg-green-100 transition-colors whitespace-nowrap">
									<i class="fas fa-check mr-1"></i>
									标记完成
								</button>
							</div>
						</div>
					</div>
					<!-- 加载状态 -->
					<div v-if="loading" class="flex justify-center items-center py-4">
						<div class="animate-spin rounded-full h-8 w-8 border-4 border-blue-500 border-t-transparent">
						</div>
					</div>
					<!-- 无更多数据提示 -->
					<div v-if="!hasMore && !loading" class="text-center text-gray-500 py-4">
						没有更多数据了
					</div>
				</div>
				<div v-else="show" class="empty-complaint-container">
					<h1 class="empty-complaint-title">真棒,暂时还没有投诉哦!</h1>
				</div>
			</div>
		</div>
		<!-- 新增投诉弹层 -->
		<div v-if="showAddComplaint" class="fixed inset-0 bg-black bg-opacity-50 z-20 flex items-center justify-center">
			<div class="bg-white rounded-lg w-[600px] p-6" @click.stop>
				<div class="flex items-center justify-between mb-6">
					<h3 class="text-xl font-medium">新建投诉</h3>
					<button @click="showAddComplaint = false" class="text-gray-400 hover:text-gray-600">
						<i class="fas fa-times"></i>
					</button>
				</div>
				<div class="space-y-4">
					<n-form ref="formRef" :model="newComplaint" :rules="rules">
						<n-form-item label="投诉标题" path="title">
							<input v-model="newComplaint.title" type="text"
								class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:border-blue-500"
								placeholder="请输入投诉标题">
						</n-form-item>
						<n-form-item label="投诉内容" path="content">
							<textarea v-model="newComplaint.content"
								class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:border-blue-500 h-32 resize-none"
								placeholder="请详细描述您的问题"></textarea>
						</n-form-item>
						<n-form-item label="反馈人姓名" path="userName">
							<input v-model="newComplaint.userName" type="text"
								class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:border-blue-500"
								placeholder="请输入您的姓名">
						</n-form-item>
						<n-form-item label="联系电话" path="userPhone">
							<input v-model="newComplaint.userPhone" type="text"
								class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:border-blue-500"
								placeholder="请输入您的联系电话">
						</n-form-item>
					</n-form>
				</div>
				<div class="flex justify-between items-center mt-6">
					<button @click="fillCaseData"
						class="!rounded-button px-4 py-2 bg-gray-100 text-gray-700 hover:bg-gray-200 text-sm whitespace-nowrap">
						<i class="fas fa-file-alt mr-2"></i>
						填充案例数据
					</button>
					<div class="flex gap-3">
						<button @click="showAddComplaint = false"
							class="!rounded-button px-4 py-2 border border-gray-300 text-gray-700 hover:bg-gray-50 text-sm whitespace-nowrap">
							取消
						</button>
						<button @click="handleSubmitComplaint"
							class="!rounded-button px-4 py-2 bg-blue-500 text-white hover:bg-blue-600 text-sm whitespace-nowrap">
							提交投诉
						</button>
					</div>
				</div>
			</div>
		</div>
	</div>
</template>
<script lang="ts" setup>
	import { ref, onMounted, computed, watch } from 'vue';
	import { JBoltApi } from '@/service/request'
	import { useWebSocketStore } from "@/stores/websocket.js";
	import { storeToRefs } from "pinia";
	import AiChat from '@/components/_builtin/jb-ai-chat/index.js'
	import * as echarts from 'echarts';
	import { list } from 'postcss';

	let currentCaseIndex = 0;
	const formRef = ref(null)
	const keywords = ref(null)
	const webSocketStore = storeToRefs(useWebSocketStore())
	const chatContainer = ref(null)
	const chatInstance = ref(null)
	const showLoading = ref(false);
	const activeMenu = ref(null);
	const show = ref(false)
	const showAddComplaint = ref(false);	// 新增投诉表单数据
	const currentSession = ref({})	//默认当前的session对象
	const chartContainer = ref<HTMLElement | null>(null);
	const loading = ref(false);
	const currentPage = ref(1);
	const pageSize = ref(10);
	const hasMore = ref(true);
	const totalComplaints = ref(0);
	const techComplaints = ref(0);
	const marketComplaints = ref(0);
	const serviceComplaints = ref(0);
	const statusClasses = {
		'待处理': 'bg-yellow-50 text-yellow-600',
		'处理中': 'bg-blue-50 text-blue-600',
		'已完成': 'bg-green-50 text-green-600',
	};
	const complaints = ref([]);
	const newComplaint = ref({
		title: '',
		content: '',
		userName: '',
		userPhone: ''
	});
	// Toast提示函数
	const showToast = (message : string) => {
		const toast = document.createElement('div');
		toast.className = 'fixed top-4 left-1/2 transform -translate-x-1/2 bg-gray-800 text-white px-4 py-2 rounded-lg shadow-lg z-50';
		toast.textContent = message;
		document.body.appendChild(toast);
		setTimeout(() => {
			document.body.removeChild(toast);
		}, 2000);
	};
	//------------数据填充
	const caseDataList = [
		{
			title: '产品性能不符合预期',
			content: '我于上个月购买了贵公司的最新型号智能手机，但使用过程中发现电池续航能力远低于广告宣传。在正常使用情况下，电池往往无法支撑一整天。此外，手机在运行大型应用时经常出现卡顿现象。这与产品宣传中"长续航"和"强劲性能"的描述严重不符。希望贵公司能够解释这一情况，并提供合理的解决方案。',
			userName: '陈志强',
			userPhone: '13912345678'
		},
		{
			title: '售后服务态度恶劣',
			content: '我在上周五购买了贵公司的一台笔记本电脑，不幸的是，设备在使用两天后出现了蓝屏问题。当我联系售后服务时，客服态度极其恶劣，不仅拒绝提供上门维修服务，还暗示是我使用不当导致的问题。这种服务态度令人非常失望，严重影响了我对贵公司的印象。希望贵公司能够重视此事，改善售后服务质量。',
			userName: '李梅',
			userPhone: '15987654321'
		},
		{
			title: '网站订单系统故障',
			content: '我在贵公司官方网站上下单购买商品时，遇到了严重的系统故障。订单提交后，页面显示成功，但我没有收到任何订单确认邮件。更糟糕的是，我的银行账户已经被扣款，但在个人中心却查不到任何订单记录。我已经尝试多次联系客服，但一直无人接听。这个问题已经困扰我两天了，严重影响了我的购物体验。希望贵公司能够尽快处理此问题，确认我的订单状态，并改进网站的订单系统。',
			userName: '王浩',
			userPhone: '13876543210'
		}
	];
	// 表单验证规则
	const rules = {
		title: {
			required: true,
			message: '请输入投诉标题',
			pattern: /\S/, // 至少有一个非空白字符
			trigger: 'change'
		},
		content: {
			required: true,
			message: '请输入投诉内容',
			pattern: /\S/, // 至少有一个非空白字符
			trigger: 'change'
		},
		userName: {
			required: true,
			message: '请输入反馈人姓名',
			pattern: /\S/, // 至少有一个非空白字符
			trigger: 'change'
		},
		userPhone: {
			required: true,
			message: '请输入反馈人联系电话',
			pattern: /^1[3-9]\d{9}$/, // 至少有一个非空白字符
			trigger: 'change'
		},
	}

	watch(() => keywords.value, () => {
		getList();
	})

	watch(() => activeMenu.value, () => {
		getList();
	})
	watch(() => webSocketStore.ws.value, () => {
		console.debug("websock重连")
		if (chatInstance.value) {
			chatInstance.value.updateWebSocket(webSocketStore.ws.value)
		}
	})
	
	watch(() => chatContainer.value, (newV) => {
		if (newV && !chatInstance.value) {
			loadChatInstance()
		}
	})
	watch(() => useWebSocketStore().ws.value, (newV) => {
	
		if (chatContainer.value && newV) {
			chatInstance.value.updateWebSocket(useWebSocketStore().ws.value)
		}
	})
	





	const fillCaseData = () => {
		newComplaint.value = { ...caseDataList[currentCaseIndex] };
		currentCaseIndex = (currentCaseIndex + 1) % caseDataList.length;
	};
	// -----------处理新增投诉
	const handleSubmitComplaint = async (callback) => {
		await formRef.value?.validate()
		showLoading.value = true;
		// console.log(chatInstance.value);
		chatInstance.value.sendMessage({
			action: 'request',
			data: {
				role: "user",
				content: { "text": newComplaint.value.title + "---" + newComplaint.value.content }
			}
		});
	};
	//添加投诉的接口
	function add(deptId) {
		const complaint = {
			title: newComplaint.value.title,
			content: newComplaint.value.content,
			status: '处理中',
			userName: newComplaint.value.userName,
			userPhone: newComplaint.value.userPhone,
			deptId: deptId,
		};
		JBoltApi.post('/complaintPush/add', complaint).then((res) => {
			showAddComplaint.value = false;
			// 重置表单
			newComplaint.value = {
				title: '',
				content: '',
				userName: '',
				userPhone: ''
			};
			getList();
			getCount();
			showLoading.value = false;
		})
	}

	//----------查询列表
	function getList() {
		JBoltApi.get('/complaintPush/list', {
			deptId: activeMenu.value,
			keywords: keywords.value,
		}).then((res) => {
			let data = res.result.data;
			if (data == null || data.length == 0) {
				show.value = false;
			} else {
				show.value = true;
				complaints.value = data;

			}
		})
	}

	//添加会话
	function addSession() {
		JBoltApi.post('/aiAppSession/add', {
			name: '新的 客户投诉智能分类 会话',
			appId: import.meta.env.VITE_APP_ID,

		}).then((res) => {
			currentSession.value = res.result.data;
			loadChatInstance();
		});
	}
	function loadChatInstance() {
		//初始化aichat
		chatInstance.value = new AiChat(chatContainer.value, {
			websocketInstance: webSocketStore.ws.value,
			app: import.meta.env.VITE_APP_ID,
			sessionId: currentSession.value.id,
			global: null,
			onMsgSend: (msg) => {
			},
			onMsgReceive: (data) => {
				if (data.action == 'response') {
					var deptId = data.data.content.text;
					//如果ai给的答案不对,那就要处理全部给客服部门
					if (deptId === "1" || deptId === "2" || deptId === "3") {
						add(deptId);
					} else {
						add(3);
					}
				}
			}
		})
	}



	
	const filteredComplaints = computed(() => {
		const filtered = activeMenu.value === null
			? complaints.value
			: complaints.value.filter(c => c.deptId === activeMenu.value);
		return filtered.slice(0, currentPage.value * pageSize.value);
	});
	const handleScroll = (e : Event) => {
		const target = e.target as HTMLElement;
		const scrollBottom = target.scrollHeight - target.scrollTop - target.clientHeight;
		if (scrollBottom < 50 && !loading.value && hasMore.value) {
			loadMore();
		}
	};
	function getCount() {
		JBoltApi.get('/complaintPush/count', {
			deptId: activeMenu.value,
			keywords: keywords.value,
		}).then((res) => {
			totalComplaints.value = res.result.data.totalComplaints;
			techComplaints.value = res.result.data.techComplaints;
			marketComplaints.value = res.result.data.marketComplaints;
			serviceComplaints.value = res.result.data.serviceComplaints;
			initEchars();
		})
	}
	const loadMore = async () => {
		if (loading.value || !hasMore.value) return;
		loading.value = true;
		try {
			// 模拟接口请求
			await new Promise(resolve => setTimeout(resolve, 1000));
			// 这里应该调用实际的加载数据接口
			// 示例：如果已加载的数据量达到总数，则设置hasMore为false
			if (currentPage.value * pageSize.value >= complaints.value.length) {
				hasMore.value = false;
			} else {
				currentPage.value++;
			}
		} finally {
			loading.value = false;
		}
	};
	function initEchars() {
		if (chartContainer.value) {
			const chart = echarts.init(chartContainer.value);
			const option = {
				animation: false,
				tooltip: {
					trigger: 'item'
				},
				legend: {
					bottom: '0',
					left: 'center'
				},
				series: [
					{
						name: '部门投诉比例',
						type: 'pie',
						radius: ['40%', '70%'],
						avoidLabelOverlap: false,
						itemStyle: {
							borderRadius: 10,
							borderColor: '#fff',
							borderWidth: 2
						},
						label: {
							show: false,
							position: 'center'
						},
						emphasis: {
							label: {
								show: true,
								fontSize: '14',
								fontWeight: 'bold'
							}
						},
						labelLine: {
							show: false
						},
						data: [
							{ value: techComplaints.value, name: '技术部' },
							{ value: marketComplaints.value, name: '市场部' },
							{ value: serviceComplaints.value, name: '客服部' },
						]
					}
				]
			};
			chart.setOption(option);
		}
	}

	onMounted(() => {
		getList();
		getCount();
		// 添加会话
		addSession();

	});
</script>
<style scoped>
	/* 优化后的容器样式 */
	.empty-complaint-container {
		display: flex;
		flex-direction: column;
		justify-content: center;
		align-items: center;
		height: 100%;
		padding: 20px;
		border: 1px solid #ccc;
		border-radius: 5px;
		box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
		background-color: #f9f9f9;
	}

	/* 优化后的标题样式 */
	.empty-complaint-title {
		font-size: 24px;
		color: #333;
		margin-bottom: 10px;
		text-align: center;
		text-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
	}

	.custom-scrollbar::-webkit-scrollbar {
		width: 6px;
	}

	.custom-scrollbar::-webkit-scrollbar-track {
		background: #f1f1f1;
	}

	.custom-scrollbar::-webkit-scrollbar-thumb {
		background: #888;
		border-radius: 3px;
	}

	.custom-scrollbar::-webkit-scrollbar-thumb:hover {
		background: #555;
	}

	input[type="number"]::-webkit-inner-spin-button,
	input[type="number"]::-webkit-outer-spin-button {
		-webkit-appearance: none;
		margin: 0;
	}
</style>